﻿#region Copyright(c) 2006 ZO, All right reserved.
// -----------------------------------------------------------------------------
// Copyright(c) 2006 ZO, All right reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//   1.  Redistribution of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//   2.  Redistribution in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//   3.  The name of the author may not be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// -----------------------------------------------------------------------------
#endregion


#region Using directives

using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using ZO.SmartCore.Helpers;
using ZO.SmartCore.Threading;

#endregion

namespace ZO.SmartCore.My4CSharp
{
    /// <summary>
    /// Represents information about an operating system, such as the version and platform identifier.
    /// </summary>
    [Browsable(false)]
    [EditorBrowsable(EditorBrowsableState.Advanced)]
    [HostProtection(SecurityAction.LinkDemand, Resources = HostProtectionResource.ExternalProcessMgmt)]
    public class OperatingSystem
    {

        #region Constructors


        #endregion

        #region Destructor

        #endregion

        #region Fields

        /// <summary>
        /// Service Pack Major Version
        /// </summary>
        private int _servicePackMajor;



        /// <summary>
        /// Gets the instance.
        /// </summary>
        /// <returns></returns>
        private static OperatingSystem GetInstance()
        {

            if (!initialized)
            {
                thisInstance.Instance.DetectWindows();
                initialized = true;
            }

            return thisInstance.Instance;
        }
        
        /// <summary>
        /// A shared OperatingSystem object
        /// </summary>
        private static readonly ThreadSafeObjectProvider<OperatingSystem> thisInstance = new ThreadSafeObjectProvider<OperatingSystem>();

        private static bool initialized;

        /// <summary>
        /// Major version number. 
        /// </summary>
        private int _major;


        /// <summary>
        /// Minor version number. 
        /// </summary>
        private int _minor;

        /// <summary>
        /// Build Version
        /// </summary>
        private int _build;
        /// <summary>
        /// latest Service Pack installed
        /// </summary>
        private string _servicePack;

        /// <summary>
        /// Operating System Name
        /// </summary>
        private string _name;

        /// <summary>
        /// Windows XP
        /// </summary>
        private bool _isXP;


        /// <summary>
        /// Windows XP
        /// </summary>
        private bool _IsXPorAbove;

        /// <summary>
        /// Windows 98
        /// </summary>
        private bool _is98;

        /// <summary>
        /// Windows 95
        /// </summary>
        private bool _is95;

        /// <summary>
        /// Windows ME
        /// </summary>
        private bool _isME;
       
        /// <summary>
        /// Windows NT
        /// </summary>
        private bool _isNT;


        /// <summary>
        /// Windows 2000
        /// </summary>
        private bool _is2000;

        /// <summary>
        /// Windows 2003
        /// </summary>
        private bool _is2003;

        /// <summary>
        /// Service Pack Minor Version
        /// </summary>
        private int _sevicePackMinor;

        #endregion

        #region Events

        #endregion

        #region Operators

        #endregion

        #region Properties

        /// <summary>
        /// Minor version number of the latest Service Pack installed on the system
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public int ServicePackMinor
        {
            get
            {
                OperatingSystem helperInstance = GetInstance();

                if (helperInstance != null)
                {
                    return helperInstance._sevicePackMinor;
                } // if
                return 0;
            } // get
        } // SevicePackMinor

        /// <summary>
        /// Major version number of the latest Service Pack installed on the system
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public int ServicePackMajor
        {
            get
            {
                OperatingSystem helperInstance = GetInstance();

                if (helperInstance != null)
                {
                    return helperInstance._servicePackMajor;
                } // if
                return 0;
            } // get
        } // ServicePackMajor

        /// <summary>
        /// Gets the Operating System Name
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public string Name
        {
            get
            {
                OperatingSystem helperInstance = GetInstance();

                if (helperInstance != null)
                {
                    return helperInstance._name;
                } // if
                return String.Empty;
            } // get
        } // Name

        /// <summary>
        ///  indicates the latest Service Pack installed on the system
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public string ServicePack
        {
            get
            {
                OperatingSystem helperInstance = GetInstance();

                if (helperInstance != null)
                {
                    return helperInstance._servicePack;
                } // if
                return String.Empty;
            } // get
        } // ServicePack

        /// <summary>
        /// Build number of the operating system.
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public int Build
        {
            get
            {
                OperatingSystem helperInstance = GetInstance();

                if (helperInstance != null)
                {
                    return helperInstance._build;
                } // if
                return 0;

            } // get
        } // Build

        /// <summary>
        /// Major version number of the operating system. 
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public int Major
        {
            get
            {
                OperatingSystem helperInstance = GetInstance();

                if (helperInstance != null)
                {
                    return helperInstance._major;
                } // if
                return 0;
            } // get
        } // Major

        /// <summary>
        /// Minor version number of the operating system
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public int Minor
        {
            get
            {
                OperatingSystem helperInstance = GetInstance();

                if (helperInstance != null)
                {
                    return helperInstance._minor;
                } // if
                return 0;
            } // get
        } // Minor

        /// <summary>
        /// Get whether Windows 2003 is installed.
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public bool Is2003
        {
            get
            {
                OperatingSystem helperInstance = GetInstance();

                if (helperInstance != null)
                {
                    return helperInstance._is2003;
                } // if

                return false;
            } // get
        } // Is2003

        /// <summary>
        /// Get whether Windows 2000 is installed.
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public bool Is2000
        {
            get
            {
                OperatingSystem helperInstance = GetInstance();

                if (helperInstance != null)
                {
                    return helperInstance._is2000;
                } // if

                return false;
            } // get
        } // Is2000

        /// <summary>
        /// Get whether Windows NT is installed.
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public bool IsNT
        {
            get
            {
                OperatingSystem helperInstance = GetInstance();

                if (helperInstance != null)
                {
                    return helperInstance._isNT;
                } // if

                return false;
            } // get
        } // IsNT

        /// <summary>
        /// Get whether Windows ME is installed.
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public bool IsME
        {
            get
            {
                OperatingSystem helperInstance = GetInstance();

                if (helperInstance != null)
                {
                    return helperInstance._isME;
                } // if

                return false;
            } // get
        } // IsME

        /// <summary>
        /// Get whether Windows 95 is installed.
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public bool Is95
        {
            get
            {
                OperatingSystem helperInstance = GetInstance();

                if (helperInstance != null)
                {
                    return helperInstance._is95;
                } // if

                return false;
            } // get
        } // Is95

        /// <summary>
        /// Get whether Windows 98 is installed.
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public bool Is98
        {
            get
            {
                OperatingSystem helperInstance = GetInstance();

                if (helperInstance != null)
                {
                    return helperInstance._is98;
                } // if

                return false;
            } // get
        } // Is98


        /// <summary>
        /// Get whether Windows XP is installed.
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public bool IsXP
        {
            get
            {
                OperatingSystem helperInstance = GetInstance();

                if (helperInstance != null)
                {
                    return helperInstance._isXP;
                } // if

                return false;
            } // get
        } // IsXP


        /// <summary>
        /// Get whether Windows XP or above is installed.
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public bool IsXPorAbove
        {
            get
            {
                OperatingSystem helperInstance = GetInstance();

                if (helperInstance != null)
                {
                    return helperInstance._IsXPorAbove;
                } // if

                return false;
            } // get
        } // IsXP
        #endregion

        #region Methods

        /// <summary>
        /// 
        /// </summary>
        private void DetectWindows()
        {
            SafeNativeMethods.OSVERSIONINFOEX versionInfoX = new SafeNativeMethods.OSVERSIONINFOEX();
            SafeNativeMethods.OSVERSIONINFO versionInfo = new SafeNativeMethods.OSVERSIONINFO();

            if (SafeNativeMethods.GetVersionEx(versionInfoX))
            {
                this._major = versionInfoX.MajorVersion;
                this._minor = versionInfoX.MinorVersion;
                this._build = NumberHelper.GetLOWord(versionInfoX.BuildNumber);
                this._servicePack = versionInfoX.CSDVersion;
                this._servicePackMajor = versionInfoX.ServicePackMajor;
                this._sevicePackMinor = versionInfoX.ServicePackMinor;

                //read windows platform
                this.ReadPlatform(versionInfoX.PlatformId);

                //read window product type
                this.ReadProduct(versionInfoX.ProductType, versionInfoX.SuiteMask);
            } // if
            else
            {
                if (!SafeNativeMethods.GetVersionEx(versionInfo))
                {
                    Win32Exception ex = new Win32Exception(Marshal.GetLastWin32Error());
                    throw new InvalidOperationException(ex.Message, ex);
                } // if
                this._major = versionInfo.MajorVersion;
                this._minor = versionInfo.MinorVersion;
                this._build = NumberHelper.GetLOWord(versionInfo.BuildNumber);
                this._servicePack = versionInfo.CSDVersion;

            } // else
        } // DetectWindows


        /// <summary>
        /// Set The Platform According To Constants
        /// </summary>
        /// <param name="platform">platformtype</param>
        private void ReadPlatform(SafeNativeMethods.OSPlatformID platform)
        {
            switch (platform)
            {
                case SafeNativeMethods.OSPlatformID.VER_PLATFORM_WIN32s:
                    this._name = "Windows 3.1";
                    break;

                case SafeNativeMethods.OSPlatformID.VER_PLATFORM_WIN32_WINDOWS:
                    if (this._minor == 0)
                    {
                        this._is95 = true;
                        this._name = "Windows 95";
                        if ((String.Compare(this._servicePack, "C", true, CultureInfo.InvariantCulture) == 0) || (String.Compare(this._servicePack, "B", true, CultureInfo.InvariantCulture) == 0))
                        {
                            this._name = "Windows 95 OSR2";
                            this._servicePack = "";
                        } // if
                    } // if
                    else if (this._minor == 10)
                    {
                        this._is98 = true;
                        this._name = "Windows 98";

                        if (String.Compare(this._servicePack, "A", true, CultureInfo.InvariantCulture) == 0)
                        {
                            this._name = "Windows 98 SE";
                            this._servicePack = "";
                        } // if
                    } // if
                    else if (this._minor == 90)
                    {
                        this._isME = true;
                        this._name = "Windows ME";
                    } // if
                    else
                    {
                        this._name = "Unknown";
                    } // else
                    break;



                case SafeNativeMethods.OSPlatformID.VER_PLATFORM_WIN32_NT:

                    if ((this._major == 3) && (this._minor == 51))
                    {
                        this._isNT = true;
                        this._name = "Windows NT 3.51";
                    } // if
                    else if ((this._major == 4) && (this._minor == 0))
                    {
                        this._isNT = true;
                        this._name = "Windows NT 4.0";
                    } // if
                    else if (this._major == 5)
                    {
                        switch (this._minor)
                        {
                            case 0:
                                this._is2000 = true;
                                this._name = "Windows 2000";
                                break;

                            case 1:
                                this._isXP = true;
                                this._name = "Windows XP";
                                this._IsXPorAbove = true;
                                break;
                            case 2:
                                this._is2003 = true;
                                this._name = "Windows 2003";
                                this._IsXPorAbove = true;
                                break;
                        } // switch
                    } // if
                    else
                    {
                        this._name = "Unknown";
                    } // else
                    break;

                case SafeNativeMethods.OSPlatformID.VER_PLATFORM_WINCE:
                    this._name = "Windows CE";
                    break;

                default:
                    this._name = "Unknown";
                    break;
            } // switch


        } // ReadPlatform

        /// <summary>
        /// Get The Operating System Product Info
        /// </summary>
        /// <param name="product">Operating System Product Type</param>
        /// <param name="suite">Operating System Suite Type</param>
        private void ReadProduct(SafeNativeMethods.OSProductType product, SafeNativeMethods.OSSuiteMask suite)
        {
            switch (product)
            {
                case SafeNativeMethods.OSProductType.VER_NT_SERVER:
                    if (this._isNT)
                    {
                        if ((suite & SafeNativeMethods.OSSuiteMask.VER_SUITE_ENTERPRISE) == SafeNativeMethods.OSSuiteMask.VER_SUITE_ENTERPRISE)
                        {
                            this._name = this._name + " Enterprise Server";
                        } // if
                        else
                        {
                            this._name = this._name + " Standard Server";
                        } // else
                    } // if

                    if (this._is2000)
                    {
                        if ((suite & SafeNativeMethods.OSSuiteMask.VER_SUITE_DATACENTER) == SafeNativeMethods.OSSuiteMask.VER_SUITE_DATACENTER)
                        {
                            this._name = this._name + " Datacenter Server";
                        } // if
                        else if ((suite & SafeNativeMethods.OSSuiteMask.VER_SUITE_ENTERPRISE) == SafeNativeMethods.OSSuiteMask.VER_SUITE_ENTERPRISE)
                        {
                            this._name = this._name + " Advanced Server";
                        } // if
                    } // if

                    if (this._is2003)
                    {
                        if ((suite & SafeNativeMethods.OSSuiteMask.VER_SUITE_DATACENTER) == SafeNativeMethods.OSSuiteMask.VER_SUITE_DATACENTER)
                        {
                            this._name = this._name + " Datacenter Server";
                        } // if
                        else if ((suite & SafeNativeMethods.OSSuiteMask.VER_SUITE_ENTERPRISE) == SafeNativeMethods.OSSuiteMask.VER_SUITE_ENTERPRISE)
                        {
                            this._name = this._name + " Enterprise Server";
                        } // if
                        else if ((suite & SafeNativeMethods.OSSuiteMask.VER_SUITE_BLADE) == SafeNativeMethods.OSSuiteMask.VER_SUITE_BLADE)
                        {
                            this._name = this._name + " Web Server";
                        } // if
                        else
                        {
                            this._name = this._name + " Standard Server";
                        } // else
                    } // if

                    break;

                case SafeNativeMethods.OSProductType.VER_NT_DOMAIN_CONTROLLER:
                    break;

                case SafeNativeMethods.OSProductType.VER_NT_WORKSTATION:
                    if (this._isNT)
                    {
                        this._name = this._name + " Workstation";
                    } // if

                    if (this._is2000)
                    {
                        this._name = this._name + " Professional";
                    } // if

                    if (this._isXP)
                    {
                        if ((suite & SafeNativeMethods.OSSuiteMask.VER_SUITE_PERSONAL) == SafeNativeMethods.OSSuiteMask.VER_SUITE_PERSONAL)
                        {
                            this._name = this._name + " Home";
                        } // if
                        else
                        {
                            this._name = this._name + " Professional";
                        } // else
                    } // if


                    break;

                case SafeNativeMethods.OSProductType.VER_UNKNOWN:
                    break;
            } // switch
        } // DetectWindows


        /// <summary>
        /// Returns a <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
        /// </returns>
        public override string ToString()
        {
            OperatingSystem helperInstance = GetInstance();

            if (helperInstance != null)
            {
                return helperInstance._name + " (" + helperInstance._servicePack + ")";
            } // if
            return String.Empty;
        } // ToString
        #endregion
    }
}
